import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.SimpleSelector;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.VCARD;

public class jenmain {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		
		String personURI = "http://somewhere/CodyJohnson";
		String fullName = "Cody Johnson";
		String givenName = "Cody";
		String familyName = "Johnson";
		
		String nickname = "Jewish";
		
		Model model = ModelFactory.createDefaultModel();
		Model model2 = ModelFactory.createDefaultModel();
		
		// Setting the namespace for a URI
		Resource codyJohnson = model.createResource(personURI);		
		Resource codyJohnson2 = model2.createResource(personURI);
		
		model.setNsPrefix( "name", personURI );
		
		// addProperty adds a "statement" which is basically a triple i.e. subject -> Predicate -> Object
		codyJohnson.addProperty( VCARD.FN, fullName );
		
		codyJohnson.addProperty( VCARD.NICKNAME, "Kodiak Bear" );
		codyJohnson.addProperty( VCARD.NICKNAME, "Another nickname" );
		
		codyJohnson2.addProperty( VCARD.NICKNAME, nickname );
		codyJohnson2.addProperty( VCARD.NICKNAME, "Kodiak Bear" );
		
		// This creates an "empty" node which is the compound of the given name and family name
		codyJohnson.addProperty( VCARD.N, model.createResource( ).addProperty( VCARD.Given, givenName ).addProperty (VCARD.Family, familyName ) );
		
		StmtIterator iter = model.listStatements();
		
		// Exploring the triple to print out the statement
		while ( iter.hasNext( ) ) 
		{
			Statement stmt = iter.nextStatement( );
			Resource subject = stmt.getSubject( );
			Property predicate = stmt.getPredicate( );
			RDFNode object = stmt.getObject( );
			
			System.out.print( subject.toString( ) );
			System.out.print( " " + predicate.toString( ) + " " );
			
			if ( object instanceof Resource)
			{
				System.out.print( object.toString() );
			}
			else
			{
				System.out.print( " \"" + object.toString() + "\"" );
			}
			System.out.println( "." );
		}
		
		// Print the model out in XML form using the "dumb" writer
		// If rdf:about is missing it represents a blank node
		// This writer doesn't take into account subsets and gives
		// blank nodes a URI (making them not blank)
		model.write( System.out );
		
		// Print the model out in XML using a different writer
		// Should not be used for large models as not efficient
		model.write( System.out, "RDF/XML-ABBREV" );
		
		System.out.println( " " );
		
		// Print the model in XML using a more efficient writer
		// However, this isn't in RDF XML form!
		model.write( System.out, "N-TRIPLE" );
		
		System.out.println( " " );
		
		// Use an iterator to print out nicknames
		// NOTE: values can come out in any order
		System.out.println( "Nicknames are:" );
		StmtIterator iter2 = codyJohnson.listProperties( VCARD.NICKNAME );
		
		while ( iter2.hasNext() )
		{
			System.out.println( iter2.nextStatement().getObject().toString() );
		}
		
		System.out.println( " " );
		
		// Print out all the full names of people in the database
		ResIterator iter3 = model.listSubjectsWithProperty( VCARD.FN );
		while ( iter3.hasNext() )
		{
			System.out.println( iter3.nextResource().getProperty( VCARD.FN ).getString() );
		}
		
		System.out.println( " " );
		
		// Print out all full names ending in Johnson using a SimpleSelector
		StmtIterator iter4 = model.listStatements( new SimpleSelector( null, VCARD.FN, (RDFNode) null ) {
			// This is an example of overriding the selects method inline
			public boolean selects(Statement s)
			{
				return s.getString().endsWith( "Johnson" );
			}
		});
		
		while ( iter4.hasNext() )
		{
			System.out.println( iter4.nextStatement().getObject().toString());
		}
		
		// Let's merge model and model2!
		Model model3 = model.union( model2 ); // there is also intersection and difference
		model3.write( System.out, "RDF/XML-ABBREV" );
		
		System.out.println( "" );
		
		model.write( System.out, "RDF/XML-ABBREV" );
		
		System.out.println( "" );
		
		model2.write( System.out, "RDF/XML-ABBREV" );
		
		System.out.println( "" );
		
		// This is what model2 has that model doesn't!
		Model model4 = model2.difference( model );
		model4.write( System.out, "RDF/XML-ABBREV" );
 
	}

}
